/** @file abstract_arguments.h
 *
 *  @author Dongryeol Lee (drselee@gmail.com)
 */

#ifndef CORE_ABSTRACT_ABSTRACT_ARGUMENTS_H
#define CORE_ABSTRACT_ABSTRACT_ARGUMENTS_H

#include <boost/program_options.hpp>
#include <string>

#include "core/data/matrix_dataset.h"

namespace core {
namespace abstract {

class AbstractArguments {
  protected:

    /** @brief The description of the arguments.
     */
    boost::program_options::options_description *desc_;

    /** @brief The variable map.
     */
    boost::program_options::variables_map vm_;

  public:

    /** @brief The absolute tolerance for detecting convergence.
     */
    double absolute_tolerance_;

    /** @brief The maximum number of iterations to run.
     */
    int max_num_iterations_;

    /** @brief The number of threads to use per each process.
     */
    int num_threads_;

    /** @brief The pointer to the query table.
     */
    core::data::Dataset *query_table_;

    /** @brief The pointer to the reference table.
     */
    core::data::Dataset *reference_table_;

    /** @brief The relative tolerance for detecting convergence.
     */
    double relative_tolerance_;

    /** @brief The output file for the model.
     */
    std::string model_out_;

    /** @brief The prediction output file.
     */
    std::string predictions_out_;

  private:

    void ValidateAbstract_() const;

    virtual bool Validate_() const = 0;

    virtual bool Parse_(
      boost::mpi::communicator &world,
      const std::vector< std::string> & args) = 0;

  public:

    AbstractArguments();

    virtual ~AbstractArguments();

    bool Parse(boost::mpi::communicator &world, int argc, char *argv[]);
};
}
}

#endif
